package com.dingtalk.video.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.video.tools.UnionVideoUtils;
import org.apache.tomcat.util.http.fileupload.FileUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Description:
 *
 * @program: video
 * @author: No.007
 * @create: 2022-04-11 15:31
 **/
@RestController
public class IndexController {
    @Autowired
    private RestTemplate restTemplate;

    private final static String PREFIX = "D:\\study\\直播回放";
    private static ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();

    @GetMapping("/addVideo")
    public String addVideo(@RequestParam String url, @RequestParam String html) {
        String liveUuid = null;
        String folderName = null;
        if (url.contains("youzan.com")) {
            JSONObject resp = JSON.parseObject(html);
            if (Objects.equals(resp.getString("code"), "0")) {
                JSONObject data = resp.getJSONObject("data");
                String alias = data.getString("alias");
                String title = data.getString("title");
                folderName = PREFIX + "\\" + title;
                liveUuid = alias;
            } else {
                System.out.println("解析异常" + url);
                return "解析异常";
            }
        } else {
            String[] split = url.split("\\?")[1].split("\\&");
            for (String s : split) {
                if (s.contains("liveUuid=")) {
                    liveUuid = s.split("=")[1];
                    break;
                }
            }
        }
        if (liveUuid == null) {
            return "未解析到必要参数";
        }
        if (StringUtils.isEmpty(html)) {
            Document document = Jsoup.parse(html);
            Elements property = document.getElementsByAttributeValue("property", "og:title");
            String content = property.attr("content");

            content = content.replaceAll(" ", "_");
            content = content.replaceAll(":", "：");
            folderName = PREFIX + "\\" + content;
        }
        File file = new File(folderName);
        if (!file.exists()) {
            file.mkdir();
            System.out.println("创建【" + folderName + "】成功");
        }
        map.put(liveUuid, folderName);
        return "解析视频名称成功";
    }

    @GetMapping("/callback")
    public String callback(@RequestParam String url) {
        String[] split = url.split("/");
        String liveUuid = split[split.length - 2];
        String folderName = map.get(liveUuid);

        File file = new File(folderName);
        if (!file.exists()) {
            file.mkdir();
            System.out.println("创建【" + folderName + "】成功");
        }

        String filename = folderName + "\\" + split[split.length - 1].split("\\?")[0];
        File file1 = new File(filename);
        if (!file1.exists()) {
            RequestCallback requestCallback = request -> request.getHeaders()
                    .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
            // 对响应进行流式处理而不是将其全部加载到内存中
            restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
                Files.copy(clientHttpResponse.getBody(), Paths.get(filename));
                System.out.println("接收到视频包：【" + filename + "】");
                return null;
            });
        }
        return "下载文件成功";
    }

    @GetMapping("/merger")
    public String merger() {
        File file = new File(PREFIX);
        if (!file.exists()) {
            return "文件夹不存在";
        }

        File[] files = file.listFiles();
        for (File folder : files) {
            if (folder.isDirectory() && !folder.getName().contains("合并")) {

                File mergerFile = new File(PREFIX + "\\合并\\" + folder.getName() + ".mp4");
                if (mergerFile.exists()) {
                    System.out.println("文件夹【" + folder.getName() + "】已完成合并");
                    continue;
                }
                System.out.println("开始合并：" + folder.getName());

                // 合并音频
                File[] fs = folder.listFiles();
                Map<Integer, File> sortMap = new HashMap<>();
                for (File f : fs) {
                    String key = f.getName().split("\\.")[0];
                    sortMap.put(Integer.valueOf(key), f);
                }

                List<String> fromVideoFileList = new ArrayList();

                Integer[] keys = sortMap.keySet().toArray(new Integer[0]);
                Arrays.sort(keys);
                for (Integer key : keys) {
                    fromVideoFileList.add(sortMap.get(key).getPath());
                }

                String outputDir = PREFIX + "\\合并\\";
                UnionVideoUtils.mergeVideo(fromVideoFileList, outputDir, mergerFile.getPath());
                System.out.println("合并成功：" + folder.getName());
            }
        }
        return "合并成功";
    }

    /**
     * 接收ts文件回调
     *
     * @param url
     * @return
     */
    @GetMapping("/callback2")
    public String callback(@RequestParam String url, @RequestParam String headers, @RequestParam String resp) {
        String liveUuid = null;

        String[] h = headers.split(",");
        for (String s : h) {
            String[] s1 = s.split(":");
            if (s1[0].contains("Referer")) {
                String[] s3 = s1[2].split("/");
                liveUuid = s3[s3.length - 1].split("\\?")[0];
                break;
            }
        }

        String folderName = map.get(liveUuid);
        if (folderName == null) {
            return "未获取到文件夹名称";
        }

        File file = new File(folderName);
        if (!file.exists()) {
            file.mkdir();
            System.out.println("创建【" + folderName + "】成功");
        }

        try {

            String[] tss = resp.split("\\\n");
            for (String ts : tss) {
                if (ts.contains("ts?sign")) {
                    System.out.println("正在解析ts：" + ts);
                    String filename = folderName + "\\" + ts.split("\\?")[0];
                    File file1 = new File(filename);
                    if (!file1.exists()) {
                        RequestCallback requestCallback = request -> request.getHeaders()
                                .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
                        // 对响应进行流式处理而不是将其全部加载到内存中
                        url = "https://mps-trans.yzcdn.cn/multi_trans_hls_hd/" + ts;
                        restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
                            Files.copy(clientHttpResponse.getBody(), Paths.get(filename));
                            System.out.println("接收到视频包：【" + filename + "】");
                            return null;
                        });
                    } else {
                        System.out.println("已存在--->> " + filename);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "下载文件成功";
    }

    @GetMapping("/merger2")
    public String merger2() {
        File file = new File(PREFIX);
        if (!file.exists()) {
            return "文件夹不存在";
        }

        File[] files = file.listFiles();
        for (File folder : files) {
            if (folder.isDirectory() && !folder.getName().contains("合并")) {

                File mergerFile = new File(PREFIX + "\\合并\\" + folder.getName() + ".mp4");
                if (mergerFile.exists()) {
                    System.out.println("文件夹【" + folder.getName() + "】已完成合并");
                    continue;
                }
                System.out.println("开始合并：" + folder.getName());

                File m = new File(PREFIX + "\\合并");

                if (!m.exists()) {
                    m.mkdirs();
                    System.out.println("已为您创建合并文件夹：" + m.getPath());
                }
                // 合并音频
                File[] fs = folder.listFiles();
                Map<Integer, File> sortMap = new HashMap<>();
                for (File f : fs) {
                    String n = f.getName();
                    String key = n.substring(n.lastIndexOf("_") + 1, n.indexOf("."));
                    sortMap.put(Integer.valueOf(key), f);
                }

                List<String> fromVideoFileList = new ArrayList();

                Integer[] keys = sortMap.keySet().toArray(new Integer[0]);
                Arrays.sort(keys);
                for (Integer key : keys) {
                    fromVideoFileList.add(sortMap.get(key).getPath());
                }

                String outputDir = PREFIX + "\\合并\\";
                UnionVideoUtils.mergeVideo(fromVideoFileList, outputDir, mergerFile.getPath());
                System.out.println("合并成功：" + folder.getName());
            }
        }
        return "合并成功";
    }
}
